//
//  HotUpdate.m
//  XYLib
//
//  Created by fantasy on 2021/6/9.
//

#import "HotUpdate.h"
#import "DownloadModule.h"
#import "FileManagerModule.h"
#import <WeexSDK/WXStorageModule.h>
#import <WeexSDK/WXUtility.h>
#import <SSZipArchive.h>

#define kBundleVersion (@"bundleVersion")
#define bundleName @"bundle.zip" 
#define BuildVersion [[NSBundle mainBundle] objectForInfoDictionaryKey:@"ResVersion"]

static NSString* docPath = @"";

@implementation HotUpdate

+(void)checkBundle{
    docPath = [WXUtility documentDirectory];
    
    //每次运行都需要检查是否有新资源需要解压
    NSString *zipPath = [docPath stringByAppendingPathComponent:bundleName];
    NSFileManager* manager = [NSFileManager defaultManager];
    if( [manager fileExistsAtPath:zipPath]){
        [HotUpdate removeBundle];
        BOOL success = [HotUpdate unzipBundleFile:zipPath toPath: docPath];//解压资源文件
        if(success){
            //解压成功，删除下载包
            [manager removeItemAtPath:zipPath error:nil];
        }else{
            //解压失败，清空解压出来的文件
            [HotUpdate removeBundle];
        }
    }
    
    NSString *startPage = [[NSBundle mainBundle].infoDictionary objectForKey:@"StartPage"];
    NSString *filePath = [docPath stringByAppendingPathComponent: startPage];
    if(![[NSFileManager defaultManager] fileExistsAtPath:filePath]){
        [HotUpdate removeBundle];
        [HotUpdate copyBundle];
    }else{
        WXStorageModule * storageModule = [[WXStorageModule alloc] init];
        NSDictionary* bundleVersion = [storageModule getItemSync:kBundleVersion];
        if (bundleVersion && [@"success" isEqualToString:bundleVersion[@"result"]]) {
            NSString* version = bundleVersion[@"data"];
            NSComparisonResult result = [BuildVersion compare:version options:NSNumericSearch];
            if (result == NSOrderedDescending) {
                //安装包中资源版本 > 本地资源版本 ，则清空本地版本，加载安装包资源
                [HotUpdate removeBundle];
                [HotUpdate copyBundle];
            }
        }
        storageModule = nil;
    }
    
    [HotUpdate checkUpdate];
}

//清空本地资源文件
+ (void)removeBundle{
    NSString*images = [docPath stringByAppendingPathComponent:@"images"];
    NSString*bundlejs = [docPath stringByAppendingPathComponent:@"bundlejs"];
    [[NSFileManager defaultManager] removeItemAtPath:images error:nil];
    [[NSFileManager defaultManager] removeItemAtPath:bundlejs error:nil];
}

//清空本地资源文件
+ (void)copyBundle{
    NSString*images = [[NSBundle mainBundle].bundlePath stringByAppendingPathComponent:@"images"];
    NSString*bundlejs = [[NSBundle mainBundle].bundlePath stringByAppendingPathComponent:@"bundlejs"];
    NSString*dstImages = [docPath stringByAppendingPathComponent:@"images"];
    NSString*dstBundlejs = [docPath stringByAppendingPathComponent:@"bundlejs"];
    [[NSFileManager defaultManager] copyItemAtPath:images toPath:dstImages error:nil];
    [[NSFileManager defaultManager] copyItemAtPath:bundlejs toPath:dstBundlejs error:nil];
}

+ (void)checkUpdate {
    __block WXStorageModule * storageModule = [[WXStorageModule alloc] init];
    
    NSDictionary* bundleVersionDic = [storageModule getItemSync:kBundleVersion];
    __block NSString * bundleVersion = nil;
    if (bundleVersionDic && [@"success" isEqualToString:bundleVersionDic[@"result"]]) {
        bundleVersion = bundleVersionDic[@"data"];
    }
    
    if ([WXUtility isBlankString:bundleVersion]) {
        bundleVersion = BuildVersion;
    }
    
    NSDictionary* commonUrl = [storageModule getItemSync:@"commonUrl"];
    NSDictionary* cmsConfig = [storageModule getItemSync:@"cmsConfig"];
    NSDictionary* updateConfig = [storageModule getItemSync:@"updateConfig"];
    if(![@"success" isEqualToString:commonUrl[@"result"]] || ![@"success" isEqualToString:cmsConfig[@"result"]]){
        [self performSelector:@selector(checkUpdate) withObject:nil afterDelay:15];
        return;
    }
    

    NSDictionary *updateDic = [WXUtility objectFromJSON:updateConfig[@"data"]];
    
    if (nil != updateDic) {
        NSString* silent =  updateDic[@"silent"];
        if (silent && [silent boolValue]) {
            return;
        }
    }
    
    NSDictionary *commonDic = [WXUtility objectFromJSON:commonUrl[@"data"]];
    NSDictionary *contentIdDic = [WXUtility objectFromJSON:cmsConfig[@"data"]];
    if (nil == commonDic || nil == contentIdDic) {
        [self performSelector:@selector(checkUpdate) withObject:nil afterDelay:15];
        storageModule = nil;
        return;
    }
    
    NSString* cmsApiHost = commonDic[@"cmsApi"]; //接口基址
    NSString* siteId = contentIdDic[@"SiteId"];
    NSString* fileName = contentIdDic[@"appVerUpdate"];
    if ([WXUtility isBlankString:cmsApiHost]) {
        cmsApiHost = commonDic[@"cmsApiHost"];
    }
    if([WXUtility isBlankString:siteId]){
        siteId = contentIdDic[@"SiteId"];
    }
    if([WXUtility isBlankString:fileName]){
        fileName = contentIdDic[@"updateApp"];
    }
    if(nil == cmsApiHost || nil == siteId ||nil == fileName){
        [self performSelector:@selector(checkUpdate) withObject:nil afterDelay:15];
        return;
    }
    
    NSString *URL = [NSString stringWithFormat:@"%@/Proxy/SiteDataSearch?SiteId=%@&FileName=%@&FileType=List&format=json",cmsApiHost,siteId,fileName];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:URL]];
        [request setHTTPMethod:@"GET"];
        
        NSHTTPURLResponse *urlResponse = nil;
        NSError *error = nil;
        NSData *recervedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
        NSString *results = [[NSString alloc] initWithBytes:[recervedData bytes] length:[recervedData length] encoding:NSUTF8StringEncoding];
        
        NSDictionary *dic = [WXUtility objectFromJSON:results];
        NSArray *infoArray = [dic objectForKey:@"Results"];
        if(nil == infoArray || ![infoArray isKindOfClass:[NSArray class]] || infoArray.count <=0){
            storageModule = nil;
            return;
        }
        
        NSDictionary * info = nil;
        for(int i=0; i < infoArray.count; i++ ){
            NSString * data = infoArray[i];
            info = [WXUtility objectFromJSON:data];
            NSString * Title = info[@"Title"];
            if(Title &&  [[Title lowercaseString] containsString:@"ios"]){
                break;
            }
        }
        if(nil == info){
            return;
        }
        
        NSString * fileUrl = info[@"bundleUrl"];    //文件下载地址
        NSString * fileMd5 = info[@"MD5"];    //文件md5检验码
        NSString * fileVersion = info[@"bundleVersion"]; //文件版本号
        NSString * minVersion = info[@"bundleForce"]; //最小版本号
        
        if([WXUtility isBlankString:fileUrl] || [WXUtility isBlankString:fileMd5] || [WXUtility isBlankString:fileVersion]){
            storageModule = nil;
            return;
        }
        
        //文件版本号校验，截取最短位数比较
        if (fileVersion.length > bundleVersion.length) {
            fileVersion = [fileVersion substringToIndex:bundleVersion.length];
        }else if (bundleVersion.length > fileVersion.length){
            bundleVersion = [bundleVersion substringToIndex:fileVersion.length];
        }
        
        NSComparisonResult result = [bundleVersion compare:fileVersion options:NSNumericSearch];
        //当前版本大于、等于最新版本，则不需要更新
        if (result != NSOrderedAscending) {
            storageModule = nil;
            return;
        }
        
        //文件版本号校验，截取最短位数比较
        if ([WXUtility isBlankString:minVersion]) {
            result = NSOrderedSame;
        }else{
            if (minVersion.length>bundleVersion.length) {
                minVersion = [minVersion substringToIndex:bundleVersion.length];
            }
            if (bundleVersion.length>minVersion.length) {
                bundleVersion = [bundleVersion substringToIndex:minVersion.length];
            }
            result = [bundleVersion compare:minVersion options:NSNumericSearch];
        }
        
        //当前版本小于最小版本，则由弹出热更新模块处理
        if (result == NSOrderedAscending) {
            storageModule = nil;
            return;
        }
        
        DownloadModule* downloader = [[DownloadModule alloc] init];
        [downloader download:fileUrl callback:^(id result, BOOL keepAlive){
            NSDictionary* info =result;
            NSString*filePath = info[@"path"];
            if(nil == filePath){
                return;
            }
            FileManagerModule* fileManager = [[FileManagerModule alloc] init];
            NSString * md5Str = [fileManager fileMD5:filePath];
            NSLog(@"\nmd5Str:%@ \nfileMd5:%@",md5Str,fileMd5);
            if([md5Str isEqualToString:fileMd5])
            {
                NSString*dstPath = [docPath stringByAppendingPathComponent:bundleName];
                if([fileManager moveItemAtPath:filePath toPath:dstPath]){
                    [storageModule setItem:kBundleVersion value:fileVersion callback:NULL];
                }else{
                    [fileManager removeItemAtPath:dstPath];
                }
                [fileManager removeItemAtPath:filePath];
            }
            storageModule = nil;
            fileManager = nil;
        }];
    });
}

+(BOOL)unzipBundleFile:(NSString*)path toPath:(NSString*)destPath{
    BOOL success = false;
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSString *key = [[NSBundle mainBundle].infoDictionary objectForKey:@"DESKEY"];
        success = [SSZipArchive unzipFileAtPath:path toDestination:destPath overwrite:YES password:key error:nil delegate:nil];
    }
    return success;
}

@end
